"""
    《最伟大的作品》的简谱
    采用 tone.py 里面预定义的频率

    参考资料：
    简谱教学入门（上），看懂音符、记住音阶：https://zhuanlan.zhihu.com/p/349054725
    树莓派GPIO：https://pinout.xyz/pinout/3v3_power
    简谱参考：https://www.bilibili.com/read/cv17437857
    简谱参考2：https://www.bilibili.com/video/BV1qr4y1u7jD
    《最伟大的作品B站原版MV》：https://www.bilibili.com/video/BV1ua411p7iA
"""

import RPi.GPIO as GPIO
import time
from GreatestWork import notation
from tone import TONE

def beep(channel: int, freq: int, duration: float, *, rising_tone: float = 1):
    """
    播放一个音符
    :param channel: GPIO的数字号
    :param freq: 频率
    :param duration: 播放时长
    :param rising_tone: 升降调 0.3 ~ 1.0 ~ 3.0
    :return:
    """
    if freq <= 0:
        time.sleep(duration)
        return
    print(get_keys(TONE, freq))
    pwm = GPIO.PWM(channel, freq * rising_tone)  # 输出该频率的电平

    try:
        pwm.start(0)
        pwm.ChangeDutyCycle(50)
        if duration > 0:
            time.sleep(duration)  # 播放时长
    finally:
        pwm.stop()


def play(channel: int, sheet: list):
    """
    播放简谱
    - [音符名(string), 持续时间(s)]
    - [频率(int), 持续时间(s)]
    :param channel: GPIO的数字号
    :param sheet: 简谱
    :return:
    """
    GPIO.setup(channel, GPIO.OUT)
    for m in sheet:
        beep(channel, TONE[m[0]] if m[0] in TONE else int(m[0] or 0), m[1])

def get_keys(d, value):
    """
    根据字典 value 获取对应的 key（用来输出显示）
    :param d: 字典
    :param value: 输入的 value值
    :return: 该 value 值对应的 key 值
    """
    return [k for k,v in d.items() if v == value]


if __name__ == '__main__':

    GPIO.setmode(GPIO.BOARD)
    # GPIO.setwarnings(False)
    gpio = 29

    try:
        play(gpio, notation)
    finally:
        GPIO.cleanup()
